package cn.cookyfly.dailyreview.server.utils;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.logging.Logger;

public class Utility {
	
	private static final Logger logger = Logger.getLogger(Utility.class.getName());

	/** 
	 * The common logger using the configuration of which is under "cn.cookyfly.dailyreview",  
	 * since in the log4j config file all loggers under that package would inherit its config 
	 * if no other specific configurations are available.
	 */
	public static String md5Digest(String input) {
		String algorithm = "MD5"; 
		try {
			return stringDigest(input, algorithm);
		} catch (NoSuchAlgorithmException e) {
			logger.severe("Initializing MessageDigest failed due to invaid algorithm: " + algorithm + 
					". Exception message: " + e.getMessage());
			return null;
		}
	}
	
	public static String shaDigest(String input) {
		String algorithm = "SHA"; 
		try {
			return stringDigest(input, algorithm);
		} catch (NoSuchAlgorithmException e) {
			logger.severe("Initializing MessageDigest failed due to invaid algorithm: " + algorithm + 
					". Exception message: " + e.getMessage());
			return null;
		}
	}

	public static String stringDigest(String input, String algorithm) throws NoSuchAlgorithmException {
		if (input == null) return null;
		if (algorithm == null) throw new NoSuchAlgorithmException("algorithm could not be null");
		MessageDigest md = null;
		md = MessageDigest.getInstance(algorithm);
		md.update(input.getBytes());
		byte[] msgDigest = md.digest();
		StringBuffer hexStrBuf = new StringBuffer(msgDigest.length);
		for (byte b : msgDigest) {
			String hex = Integer.toHexString(0xFF & b);
			if (hex.length() == 1) hexStrBuf.append('0');
			hexStrBuf.append(hex);
		}
		return hexStrBuf.toString();
	}

	/**
	 * Get the absolute path of the provided Java class file.
	 * The provided Java class must not be either a system class (i.g. from JDK), or a class in a .jar file.
	 *
	 * @param cls Java Class
	 * @return the absolute path of the class file (in an OS-dependent format)
	 */
	public static String getPath(Class<?> cls) {
		try {
			String clsName = cls.getName();
			String clsFileName = clsName.substring(clsName.lastIndexOf('.') +
					1) + ".class";
			String absoPath = cls.getResource(clsFileName).getPath();
			return absoPath;
		} catch (NullPointerException e) {
			return null;
		}
	}

	/**
	 * NOTICE: available ONLY in Unix and GNU/Linux OS
	 */
	public static String getClassPath(Class<?> cls) {
		String absoPath = getPath(cls);
		if (absoPath == null) return null;
		String clsName = cls.getName();
		String tailPath = clsName.replace('.', '/') + ".class";
		String clsFolder = absoPath.substring(0, absoPath.lastIndexOf(tailPath));
		return clsFolder;
	}

	/**
	 * NOTICE: available ONLY in Unix and GNU/Linux OS.
	 * Also, the method does NOT validate if the provided path is valid.
	 */
	public static String getParentPath(String path) {
		if (path == null) return null;
		/*
		 * if 'path' has only one character, -1 would be specified to 'pos',
		 * then null will be returned since the 'path' must be invalid (except
		 * it's '/', in which case null if also should be returned as the root
		 * folder has no parent path).
		 */
		int pos = path.lastIndexOf('/', path.length() - 2);
		if (pos < 0) return null;
		return path.substring(0, pos + 1);
	}
	
}
